package cn.analysys.test;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Job;
import org.activiti.engine.runtime.ProcessInstance;

import java.io.FileNotFoundException;

/**
 *
 * 工作管理
 *      异步任务（一般工作表：act_ru_job）
 *      定时事件 （定时工作表：act_ru_timer_job）
 *      暂停的工作 （暂停工作表：act_ru_suspended_job）
 *      无法执行的工作 （无法执行的任务工作表：act_ru_deadletter_job）
 *
 * 工作转移与删除
 *
 */
public class JobTest5 {

    public static void main(String[] args) throws FileNotFoundException, InterruptedException {
        // 创建一般异步任务
//        normalJob();

        // 创建定时任务
//        timerJob();

        // 中止流程
//        suspendJob();

        // 无法执行的任务
//        deadletterJob();

        // 工作转移与删除
        deleteJob();
    }

    /**
     *  创建一般异步任务
     *  1.创建job执行类：myjavadelegatejob类
     *  2.service_task.bpmn中增加activiti:class、activiti:async配置，将job执行添加进来
     *  3.activiti.cfg.xml中增加异步执行器（asyncExecutorActivate）
     *  4.启动流程
     */
    public static void normalJob() throws FileNotFoundException {
        // 创建流程引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 存储服务
        RepositoryService repositoryService = engine.getRepositoryService();
        // 创建任务服务
        TaskService taskService = engine.getTaskService();
        // 运行时服务
        RuntimeService runtimeService = engine.getRuntimeService();
        // 部署流程定义
        Deployment deployment = repositoryService.createDeployment().addClasspathResource("datas/service_task.bpmn").deploy();
        // 查询流程定义实体 (查询：act_re_procdef)
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        // 启动流程后，act_ru_execution表有数据添加
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinition.getKey());
        System.out.println(processInstance.getId() );
    }


    /**
     *  创建定时事件任务
     *  1.创建job执行类：myjavadelegatejob类
     *  2.service_task.bpmn中增加activiti:class、activiti:async配置，将job执行添加进来
     *  3.activiti.cfg.xml中增加异步执行器（asyncExecutorActivate）
     *  4.启动流程
     */
    public static void timerJob() throws FileNotFoundException {
        // 创建流程引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 存储服务
        RepositoryService repositoryService = engine.getRepositoryService();
        // 创建任务服务
        TaskService taskService = engine.getTaskService();
        // 运行时服务
        RuntimeService runtimeService = engine.getRuntimeService();
        // 部署流程定义
        Deployment deployment = repositoryService.createDeployment().addClasspathResource("datas/timer_test.bpmn").deploy();
        // 查询流程定义实体 (查询：act_re_procdef)
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        // 启动流程后，act_ru_execution表有数据添加
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinition.getKey());
        System.out.println(processInstance.getId() );
    }


    /**
     *  暂停的工作
     *      在定时任务等待时，中止流程。
     */
    public static void suspendJob() throws FileNotFoundException, InterruptedException {
        // 创建流程引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 存储服务
        RepositoryService repositoryService = engine.getRepositoryService();
        // 创建任务服务
        TaskService taskService = engine.getTaskService();
        // 运行时服务
        RuntimeService runtimeService = engine.getRuntimeService();
        // 部署流程定义
        Deployment deployment = repositoryService.createDeployment().addClasspathResource("datas/timer_test.bpmn").deploy();
        // 查询流程定义实体 (查询：act_re_procdef)
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        // 启动流程后，act_ru_execution表有数据添加
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinition.getKey());
        System.out.println(processInstance.getId() );

        Thread.sleep(10000);

        // 中止流程
        runtimeService.suspendProcessInstanceById(processInstance.getId());

        Thread.sleep(10000);

        // 激活流程
        runtimeService.activateProcessInstanceById(processInstance.getId());
    }


    /**
     *  无法执行的任务
     *      如果工作在执行时发生异常，可以进行重新执行，默认下工作最大执行次数为3次。
     *      可以使用 ManagementService.setJobRetries()方法来设置重试次数。
     *      当一个工作执行了多次，仍然是失败的，那么acitiviti就会将其写入act_ru_deadletter_job表
     */
    public static void deadletterJob() {
        // 创建流程引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 存储服务
        RepositoryService repositoryService = engine.getRepositoryService();
        // 运行时服务
        RuntimeService runtimeService = engine.getRuntimeService();

        // 管理服务
        ManagementService managementService = engine.getManagementService();

        // 部署流程定义
        Deployment deployment = repositoryService.createDeployment().addClasspathResource("datas/error_task.bpmn").deploy();
        // 查询流程定义实体 (查询：act_re_procdef)
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        // 启动流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinition.getKey());
        System.out.println(processInstance.getId());

        Job job = managementService.createJobQuery().singleResult();
        // 设置任务重试次数
        managementService.setJobRetries(job.getId(), 1);
        // 重新执行该工作
        managementService.executeJob(job.getId());

        // 查询无法执行的任务
        long deadCout = managementService.createDeadLetterJobQuery().count();
    }


    /**
     * 移动和删除任务
     */
    public static void deleteJob() throws FileNotFoundException {
        // 创建流程引擎
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 存储服务
        RepositoryService repositoryService = engine.getRepositoryService();
        // 运行时服务
        RuntimeService runtimeService = engine.getRuntimeService();
        // 部署流程定义
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("datas/service_task.bpmn").deploy();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId()).singleResult();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinition.getKey());
        System.out.println(processInstance.getId() );

        // 管理服务
        ManagementService managementService = engine.getManagementService();
        Job job = managementService.createJobQuery().singleResult();
        Job deadLetterJob = managementService.createDeadLetterJobQuery().singleResult();

        // 将一般工作移动到deadletter表
        managementService.moveJobToDeadLetterJob(job.getId());
        // 将deadletter移动到一般工作
        managementService.moveDeadLetterJobToExecutableJob(deadLetterJob.getId(),2);
        // 删除一般工作
        managementService.deleteJob(job.getId());

    }
}
